// #include <iostream>
// #include <sys/types.h>
// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <unistd.h>
// #include <stdlib.h>
// #include <arpa/inet.h>

// #include <cstring>
// #include <string>
// #include <thread>
// #include <cjson/cJSON.h>

// // #include "../proto/login.pb.h"
 
// #define MAXLINE 4096
// #define SERVER_PORT 8001
// #define SERVER_ADDR "127.0.0.1"
 
// using namespace std;


// struct Packet{
//     unsigned short head;
//     unsigned short pbTypeLen;
//     char buff[MAXLINE - 4];
// };

// bool bClose = false;

// void recvPacket(int fd){
//     char recvbuff[MAXLINE];
//     unsigned short head;
//     Packet packet;
//     while (!bClose)
//     {
//         int ret = recv(fd, recvbuff, 2, 0);
//         if(ret > 0){
//             memcpy(&head, recvbuff, 2);
//             head = ntohs(head);

//             memset(recvbuff, 0, MAXLINE);
//             ret = recv(fd, recvbuff, head, 0);
//             if(ret > 0){
//                 unsigned short pbTypeLen;
//                 memcpy(&pbTypeLen, recvbuff, 2);
//                 pbTypeLen = ntohs(pbTypeLen);

//                 char pbType[MAXLINE];
//                 char body[MAXLINE];
//                 memcpy(&pbType, recvbuff + 2, pbTypeLen);
//                 memcpy(body, recvbuff + 2 + pbTypeLen, head - 2 - pbTypeLen);

//                 login::retLoginMsg loginmsg2;
//                 loginmsg2.ParseFromString(body);
//                 cout << loginmsg2.cmd() << " " << loginmsg2.status() << " " << loginmsg2.msg() << endl;
//             }else{
//                 cout << "exit recv1" << endl;
//                 bClose = true;
//                 break;
//             }
//         }else{
//             cout << "exit recv2" << endl;
//             bClose = true;
//             break;
//         }

//         memset(recvbuff, 0, MAXLINE);
//     }
// }


// cJSON* loginJson(){
//     cout << "请输入账号" << endl;
//     char username[MAXLINE];
//     cin >> username;

//     cout << "请输入密码" << endl;
//     char password[MAXLINE];
//     cin >> password;

//     cJSON* json = cJSON_CreateArray();
//     cJSON_AddItemToArray(json, cJSON_CreateString("login"));
//     cJSON_AddItemToArray(json, cJSON_CreateString(username));
//     cJSON_AddItemToArray(json, cJSON_CreateString(password));

//     return json;
// }

// const char* loginpb(){
//     cout << "请输入账号" << endl;
//     char username[MAXLINE];
//     cin >> username;

//     cout << "请输入密码" << endl;
//     char password[MAXLINE];
//     cin >> password;

//     login::loginmsg loginmsg;
//     loginmsg.set_cmd("login");
//     loginmsg.set_username(username);
//     loginmsg.set_pwd(password);
//     // 编码
//     return loginmsg.SerializeAsString().c_str();
// }

// const char* register_pb(){
//     cout << "请输入注册的用户名" << endl;
//     char username[MAXLINE];
//     cin >> username;

//     cout << "请输入注册的密码" << endl;
//     char password[MAXLINE];
//     cin >> password;

//     cout << "请确认注册的密码" << endl;
//     char password2[MAXLINE];
//     cin >> password2;

//     login::Register registerMsg;
//     registerMsg.set_cmd("register");
//     registerMsg.set_username(username);
//     registerMsg.set_password1(password);
//     registerMsg.set_password2(password2);
//     return registerMsg.SerializeAsString().c_str();
// }

// void test1(){
//     int clientfd;
//     struct sockaddr_in seraddr;
//     Packet* packet = new Packet();
//     char sendbuff[MAXLINE];
//     char pbType[MAXLINE];
 
//     memset(sendbuff, 0, sizeof(sendbuff));
//     memset(sendbuff, 0, sizeof(pbType));
//     memset(&seraddr,0,sizeof(seraddr));
//     seraddr.sin_family = AF_INET;
//     seraddr.sin_port = htons(SERVER_PORT);
//     seraddr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
 
//     if (-1==(clientfd = socket(PF_INET,SOCK_STREAM,0)))
//     {
//         cout<<"create socket error!"<<endl;
//         return;
//     }
    
//     if (-1 == connect(clientfd, (struct sockaddr*)&seraddr, sizeof(seraddr)))
//     {
//         cout << "connect failed" << endl;
//         return;
//     }

//     thread t(recvPacket, clientfd);
    
//     cJSON* json;
//     const char* pbsz = "";
//     cin >> packet->buff;
//     while (0 != strcmp(packet->buff, "quit") && !bClose)
//     {
//         cout << "cin:" << packet->buff << endl;
//         if(strcmp(packet->buff, "login") == 0){
//             // json = loginJson();
//             pbsz = loginpb();
//             strcpy(pbType, "login.loginmsg");
//         }
//         else if(strcmp(packet->buff, "register") == 0){
//             pbsz = register_pb();
//             strcpy(pbType, "login.Register");
//         }else if(strcmp(packet->buff, "exit") == 0){
//             login::Logout logout;
//             logout.set_cmd("exit");
//             pbsz = logout.SerializeAsString().c_str();
//             strcpy(pbType, "login.Logout");
//             // cout << "输入错误" << endl;
//             // memset(packet, 0, sizeof(packet));
//             // cin >> packet->buff;
//             // continue;
//             // json = cJSON_CreateArray();
//             // cJSON_AddItemToArray(json, cJSON_CreateString(packet->buff));
//         }else if(strcmp(packet->buff, "logout") == 0){
//             login::Logout logout;
//             logout.set_cmd("logout");
//             pbsz = logout.SerializeAsString().c_str();
//             strcpy(pbType, "login.Logout");
//         }

//         // char* jsonPacked = cJSON_PrintUnformatted(json);
//         // unsigned short len = strlen(jsonPacked);

//         unsigned short len = strlen(pbsz);
//         unsigned short pbTypeLen = strlen(pbType);
//         cout << "pbType:" << pbType << " pbTypeLen:" << pbTypeLen << endl;

//         unsigned short totollen = len + sizeof(unsigned short) + pbTypeLen;
//         packet->head = ntohs(totollen);
//         packet->pbTypeLen = ntohs(pbTypeLen);
        
//         memcpy(packet->buff, pbType, pbTypeLen);
//         memcpy(packet->buff + pbTypeLen, pbsz, MAXLINE - pbTypeLen);
//         memcpy(sendbuff, packet, MAXLINE);
//         ssize_t ret = send(clientfd, sendbuff, totollen + 2, 0);
//         if (ret <= 0)
//         {
//             cout << "ret <= 0, exit send" << endl;
//             break;
//         }
//         cout<< "send msg: " << " success " << ret <<endl;

//         memset(sendbuff, 0, sizeof(sendbuff));
//         memset(packet, 0, sizeof(packet));
//         memset(pbType, 0, sizeof(pbType));
//         // cJSON_Delete(json);
//         cin >> packet->buff;
//     }
    
//     bClose = true;
//     delete packet;
//     close(clientfd);
// }

// void test2(){
//     char c[1024] = "hello";
//     cJSON* json = cJSON_CreateArray();

//     cJSON_AddItemToArray(json, cJSON_CreateString(c));
//     cout << cJSON_Print(json) << endl;;
// }

// void test3(){
//     login::loginmsg loginmsg;
//     loginmsg.set_cmd("login");
//     loginmsg.set_username("111");
//     loginmsg.set_pwd("123");
//     // 编码
//     string szpb = loginmsg.SerializeAsString();
//     cout << szpb << endl;

//     // 解码
//     login::loginmsg loginmsg2;
//     loginmsg2.ParseFromString(szpb);
//     cout << loginmsg2.cmd() << " " << loginmsg2.username() << " " << loginmsg2.pwd() << endl;

//     google::protobuf::ShutdownProtobufLibrary();
// }


// #include <functional>

// std::function<int(void)> f;
// void test4(){
//     int* a = new int(100);
//     auto lf = [&a]() -> decltype(*a){
//         cout << *a << endl;
//         return *a;
//     };

//     // 危险，需要在lambda调用之后delete，否则a为悬空引用
//     // delete a;
//     f = lf;

//     f();
//     delete a;
// }
 
// int main()
// {
//     // test1();
//     // test2();
//     // test3();
//     test4();
//     return 0;
// }